package com.sourcegraph.cody.ui

import com.sourcegraph.cody.chat.PromptHistory
import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
import javax.swing.JTextArea
import javax.swing.text.DefaultEditorKit

class TextAreaHistoryManager(textArea: JTextArea, val promptHistory: PromptHistory) {

  // When "history mode" is enabled, pressing Up/Down arrow keys replaces the chat input with the
  // previous/next chat message. History mode can only be activated when the chat input is empty,
  // and it's deactivated on the first key action that is not an Up/Down arrow key.
  private var isInHistoryMode = true

  init {
    textArea.addKeyListener(
        object : KeyAdapter() {
          override fun keyPressed(e: KeyEvent) {
            val shouldEnterHistoryMode = textArea.getText().isEmpty()
            if (e.keyCode != KeyEvent.VK_UP && e.keyCode != KeyEvent.VK_DOWN ||
                shouldEnterHistoryMode) {
              if (isInHistoryMode.not() && shouldEnterHistoryMode) {
                promptHistory.resetHistory()
              }
              isInHistoryMode = shouldEnterHistoryMode
            }
            if (e.keyCode == KeyEvent.VK_UP) {
              if (isInHistoryMode) {
                val previous = promptHistory.getPrevious() ?: return
                textArea.text = previous
                textArea.moveCaretPosition(textArea.text.length)
                e.consume()
              } else {
                val defaultAction = textArea.actionMap[DefaultEditorKit.upAction]
                defaultAction.actionPerformed(null)
              }
            } else if (e.keyCode == KeyEvent.VK_DOWN) {
              if (isInHistoryMode) {
                val next = promptHistory.getNext()
                if (next.isNullOrEmpty()) {
                  promptHistory.resetHistory()
                }
                textArea.text = next
                textArea.moveCaretPosition(textArea.text.length)
                e.consume()
              } else {
                val defaultAction = textArea.actionMap[DefaultEditorKit.downAction]
                defaultAction.actionPerformed(null)
              }
            }
          }

          /* For some reason the event generated by the backspace key is not caught in keyPressed.
          It is consumed somewhere before by the IDE. Hence, we need to provide a proper handling of the event here. */
          override fun keyReleased(e: KeyEvent) {
            if (e.keyCode != KeyEvent.VK_UP && e.keyCode != KeyEvent.VK_DOWN) {
              isInHistoryMode = textArea.getText().isEmpty()
              promptHistory.resetHistory()
            }
          }
        })
  }

  fun addPrompt(prompt: String) {
    promptHistory.add(prompt)
    isInHistoryMode = true
  }

  fun isHistoryAvailable(): Boolean {
    return isInHistoryMode && promptHistory.isNotEmpty()
  }
}
